import { FormRules } from 'naive-ui'
import { useI18n } from 'vue-i18n'

import { createMenu, updateMenu } from '@/apis'
import { MenuModalDto } from '@/apis/menu/type/dto'
import { useRef } from '@/hooks'
import { MenuTypeEnum, StatusEnum } from '@/types/enum'
import { FormInputList, FormInputListRules } from '@/types/interface'
import { catchToTuple } from '@/utils'

export function useModal({ tableData, init }: any) {
  const { t } = useI18n()
  const modalShow = ref<boolean>(false)
  const modalType = ref<'create' | 'update'>('create')

  // 表单数据
  const [modalFormData, handleModalFormDataReset] = useRef<MenuModalDto>({
    name: '',
    key: '',
    i18n_key: '',
    icon: '',
    sort: 1,
    comp_type: MenuTypeEnum.DIRECTORY,
    path: '',
    comp_url: '',
    parent_id: null,
    permission: '',
    hidden: StatusEnum.STATIC,
    status: StatusEnum.DYNAMIC,
  })

  // 定义不同类型下的额外字段配置
  const extraFieldsMapping: Record<number, () => FormInputList<MenuModalDto>> = {
    [MenuTypeEnum.DIRECTORY]: () => [
      {
        key: 'path',
        type: 'input',
        label: t('menus.path'),
        placeholder: t('common.please_enter', { name: t('menus.name') }),
        span: 12,
      },
      {
        key: 'icon',
        type: 'input',
        label: t('menus.icon'),
        placeholder: t('common.please_enter', { name: t('menus.name') }),
        span: 12,
      },
      {
        key: 'hidden',
        type: 'radio',
        label: t('common.hidden'),
        placeholder: t('common.please_select', { name: t('menus.name') }),
        options: [
          { label: t('common.status_enable'), value: StatusEnum.DYNAMIC },
          { label: t('common.status_disable'), value: StatusEnum.STATIC },
        ],
        span: 12,
      },
    ],
    [MenuTypeEnum.MENU]: () => [
      {
        key: 'icon',
        type: 'input',
        label: t('menus.icon'),
        placeholder: t('common.please_enter', { name: t('menus.name') }),
        span: 12,
      },
      {
        key: 'path',
        type: 'input',
        label: t('menus.path'),
        placeholder: t('common.please_enter', { name: t('menus.name') }),
        span: 12,
      },
      {
        key: 'comp_url',
        type: 'input',
        label: t('menus.comp_url'),
        placeholder: t('common.please_enter', { name: t('menus.name') }),
        span: 12,
      },
      {
        key: 'permission',
        type: 'input',
        label: t('menus.permission'),
        placeholder: t('common.please_enter', { name: t('menus.name') }),
        span: 12,
      },
      {
        key: 'hidden',
        type: 'radio',
        label: t('common.hidden'),
        placeholder: t('common.please_select', { name: t('menus.name') }),
        options: [
          { label: t('common.status_enable'), value: StatusEnum.DYNAMIC },
          { label: t('common.status_disable'), value: StatusEnum.STATIC },
        ],
        span: 12,
      },
    ],
    [MenuTypeEnum.BUTTON]: () => [
      {
        key: 'permission',
        type: 'input',
        label: t('menus.permission'),
        placeholder: t('common.please_enter', { name: t('menus.name') }),
        span: 12,
        labelTips: 'system:permission:**',
      },
    ],
  }

  // 定义不同类型下的校验规则映射
  const rulesMapping: Record<number, FormRules> = {
    [MenuTypeEnum.DIRECTORY]: {
      path: [
        {
          required: true,
          renderMessage: () => t('common.please_enter', { name: t('menus.path') }),
          trigger: ['input'],
        },
      ],
    },
    [MenuTypeEnum.MENU]: {
      path: [
        {
          required: true,
          renderMessage: () => t('common.please_enter', { name: t('menus.path') }),
          trigger: ['input'],
        },
      ],
      comp_url: [
        {
          required: true,
          renderMessage: () => t('common.please_enter', { name: t('menus.comp_url') }),
          trigger: ['input'],
        },
      ],
      permission: [
        {
          required: true,
          renderMessage: () => t('common.please_enter', { name: t('menus.permission') }),
          trigger: ['input'],
        },
      ],
      hidden: [
        {
          required: true,
          renderMessage: () => t('common.please_select', { name: t('common.hidden') }),
          trigger: ['change'],
        },
      ],
    },
    [MenuTypeEnum.BUTTON]: {
      permission: [
        {
          required: true,
          renderMessage: () => t('common.please_enter', { name: t('menus.permission') }),
          trigger: ['input'],
        },
      ],
    },
  }

  // 表单配置
  const modalFormList = computed((): FormInputList<MenuModalDto> => {
    return [
      {
        key: 'parent_id',
        type: 'tree-select',
        label: t('menus.parent_id'),
        placeholder: t('common.please_enter', { name: t('menus.parent_id') }),
        options: tableData.value,
        keyField: 'id',
        labelField: 'name',
        childrenField: 'children',
        labelTips: '没有选择则为顶层目录',
      },
      {
        key: 'comp_type',
        type: 'radio',
        label: t('menus.comp_type'),
        placeholder: t('common.please_enter', { name: t('menus.comp_type') }),
        options: [
          { label: t('menus.directory'), value: MenuTypeEnum.DIRECTORY },
          { label: t('menus.menu'), value: MenuTypeEnum.MENU },
          { label: t('menus.button'), value: MenuTypeEnum.BUTTON },
        ],
      },
      {
        key: 'name',
        type: 'input',
        label: t('menus.name'),
        placeholder: t('common.please_enter', { name: t('menus.name') }),
        span: 12,
      },
      {
        key: 'key',
        type: 'input',
        label: t('menus.key'),
        placeholder: t('common.please_enter', { name: t('menus.key') }),
        span: 12,
      },
      {
        key: 'i18n_key',
        type: 'input',
        label: t('menus.i18n_key'),
        placeholder: t('common.please_enter', { name: t('menus.i18n_key') }),
        span: 12,
      },
      {
        key: 'sort',
        type: 'input-number',
        label: t('common.sort'),
        placeholder: t('common.please_enter', { name: t('common.sort') }),
        span: 12,
      },
      {
        key: 'status',
        type: 'radio',
        label: t('common.status'),
        placeholder: t('common.please_select', { name: t('common.status') }),
        options: [
          { label: t('common.status_enable'), value: StatusEnum.DYNAMIC },
          { label: t('common.status_disable'), value: StatusEnum.STATIC },
        ],
        span: 12,
      },
      ...(modalFormData.value.comp_type ? extraFieldsMapping[modalFormData.value.comp_type]() : []),
    ]
  })

  // 表单校验规则
  const modalFormRules = computed((): FormInputListRules<MenuModalDto> => {
    return {
      name: [
        {
          required: true,
          renderMessage: () => t('common.please_enter', { name: t('menus.name') }),
          trigger: ['input'],
        },
      ],
      key: [
        {
          required: true,
          renderMessage: () => t('common.please_enter', { name: t('menus.key') }),
          trigger: ['input'],
        },
      ],
      i18n_key: [
        {
          required: true,
          renderMessage: () => t('common.please_enter', { name: t('menus.i18n_key') }),
          trigger: ['input'],
        },
      ],
      comp_type: [
        {
          required: true,
          renderMessage: () => t('common.please_select', { name: t('menus.name') }),
          trigger: ['change'],
        },
      ],
      sort: [
        {
          type: 'number',
          required: true,
          renderMessage: () => t('common.please_enter', { name: t('common.sort') }),
          trigger: ['input'],
        },
      ],
      status: [
        {
          required: true,
          renderMessage: () => t('common.please_select', { name: t('common.status') }),
          trigger: ['change'],
        },
      ],
      ...(modalFormData.value.comp_type ? rulesMapping[modalFormData.value.comp_type] : null),
    }
  })

  // 取消
  const handleModalCancel = () => {
    modalShow.value = false
    handleModalFormDataReset()
  }

  // 提交
  const handleModalSubmit = async () => {
    const [err, data] = await catchToTuple(
      modalType.value === 'update' ? updateMenu(modalFormData.value) : createMenu(modalFormData.value),
    )

    if (err) return

    if (data?.code === 200) {
      window.$message.success(data.message)
      handleModalCancel()
      init()
    }
  }

  return {
    modalShow,
    modalType,
    modalFormData,
    modalFormList,
    modalFormRules,
    handleModalCancel,
    handleModalSubmit,
    handleModalFormDataReset,
  }
}
